package cn.itsource.hrm.service.impl;

import cn.itsource.feign.client.RedisFeignClient;
import cn.itsource.hrm.contants.RedisConstants;
import cn.itsource.hrm.domain.CourseType;
import cn.itsource.hrm.mapper.CourseTypeMapper;
import cn.itsource.hrm.service.ICourseTypeService;
import cn.itsource.hrm.utils.AjaxResult;
import cn.itsource.hrm.vo.CrumbsVo;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 课程目录 服务实现类
 * </p>
 *
 * @author luo
 * @since 2020-04-18
 */
@Service
//开启事务
@Transactional
public class CourseTypeServiceImpl extends ServiceImpl<CourseTypeMapper, CourseType> implements ICourseTypeService {

    @Autowired
    private RedisFeignClient redisFeignClient;
    //查询课程分类，加入缓存逻辑
    private List<CourseType> selectCourseTypeFromCache(){
        //1.从Redis中查询课程分类
        AjaxResult key_course_type = redisFeignClient.get(RedisConstants.KEY_COURSE_TYPE);
        if(key_course_type.isSuccess() && key_course_type.getResultObj() != null){
            //通过判断 拿到了数据
            //1.把课程分类取出来.把json数据转成list
            String courseTypeJson = key_course_type.getResultObj().toString();
            return JSON.parseArray(courseTypeJson, CourseType.class);
        }
        //3.没有查询出课程分类 就直接查询mysql 然后放入redis
        List<CourseType> courseTypes = courseTypeToRedisFromMysql();
        //4.返回课程分类
        return courseTypes;
    }

    private List<CourseType> courseTypeToRedisFromMysql() {
        List<CourseType> courseTypes = baseMapper.selectList(null);
        redisFeignClient.set(RedisConstants.KEY_COURSE_TYPE, JSON.toJSONString(courseTypes));
        return courseTypes;
    }


    @Override
    public List<CourseType> treeData() {

        ArrayList<CourseType> list = new ArrayList<>();
        //1.把所有的分类数据查询出来 调用上面的方法
        List<CourseType> allCourseType = selectCourseTypeFromCache();
        allCourseType.forEach(currentCourseType ->{
            //2.把一级分类找出来，装到List中
            if(currentCourseType.getPid() == 0){
                //到这里，就是一级
                list.add(currentCourseType);
            }else{
                //这里可能是二级，也有可能是三级。
                //3.除开一级分类的其他所有的分类，都去找自己的父分类，装到父分类的children 每一次循环都会去找及自己父分类
                for(CourseType parentCouresType : allCourseType){
                    //父分类的 id = currentCourseType.pid
                    if(currentCourseType.getPid().equals(parentCouresType.getId())){
                        //3.2.加入自己的父分类的children
                        parentCouresType.getChildren().add(currentCourseType);
                        break;
                    }
                }
            }
        });
        return list;
    }

    @Override
    public List<CrumbsVo> crumbs(Long courseTypeId) {

        //1.通过id查询出当前分类
        CourseType courseType = baseMapper.selectById(courseTypeId);
        //2.获取到当前分类的path，；里面可以分割为多个id的数组 放到集合里面
        String path = courseType.getPath();
        //3.调用字符串的方法  需要转义
        String[] split = path.split("\\.");
        ArrayList<Long> ids = new ArrayList<>();
        for (String id: split) {
            ids.add(Long.valueOf(id));
        }
        //4.通过上面的id 批量查询
        List<CourseType> courseTypes = baseMapper.selectBatchIds(ids);

        //5.遍历程分类列表
        List<CrumbsVo> result = new ArrayList<>() ;
        courseTypes.forEach( currentCourseType -> {
            //把当前课程分类封装到vo
            CrumbsVo  vo = new CrumbsVo();
            //保存自己
            vo.setOwnerProductType(currentCourseType);
            //为每一个课程类型找他的兄弟姐妹列表，设置到兄弟姐妹字段 通过pid
            Long pid = currentCourseType.getPid();
            List<CourseType> otherProductTypes = baseMapper.selectListByPid(pid);
            //把这个pid设置到vo对象
            vo.setOtherProductTypes(otherProductTypes);
            //添加到list
            result.add(vo);
        });

        //6.最后返回结果List
        return result;

    }

    @Override
    public boolean insert(CourseType entity) {
        boolean insert = super.insert(entity);;
        //判断是否有值
        if (insert){
            courseTypeToRedisFromMysql();
        }
        return insert;
    }

    @Override
    public boolean deleteById(Serializable id) {
        boolean delete = super.deleteById(id);
        if (delete){
            courseTypeToRedisFromMysql();
        }
        return delete;

    }

    @Override
    public boolean updateById(CourseType entity) {
        boolean update = super.updateById(entity);
        if (update){
            courseTypeToRedisFromMysql();
        }
        return update;
    }
}
